home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / fio.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  31KB  |  1,231 lines

  1. /*
  2.  * $Id: fio.c,v 0.91 1994/02/20 00:53:00 zhao Pre-Release $
  3.  *
  4.  *. This file is part of BIT shareware package. After the two weeks of
  5.  *  free evaluation period, you are encouraged (required) to register
  6.  *  your copy for a small registration fee, which is $35 for personal use
  7.  *  and $50 for commercial, government and institutional use.
  8.  *
  9.  *  Copyright(c) 1993, 1994 by T.C. Zhao.
  10.  *  All rights reserved.
  11.  *
  12.  *  Permission to use, copy, and distribute this software in its entirety
  13.  *  for non-commercial purposes is hereby granted, provided that the
  14.  *  above shareware and copyright notices and this permission notice
  15.  *  appear in all copies and their documentation.
  16.  *
  17.  *  This software may be modified for your own use, but modified versions
  18.  *  may not be distributed without prior consent of the author.
  19.  *
  20.  *  This software is provided "as is" without expressed or implied
  21.  *  warranty of any kind.
  22.  *
  23.  *.
  24.  * GUI part of the file stuff: A file selector. Custom file loader dumper.
  25.  *
  26.  */
  27. #if !defined(lint) && defined(F_ID)
  28. char *id_fio = "$Id: fio.c,v 0.91 1994/02/20 00:53:00 zhao Pre-Release $";
  29. #endif
  30.  
  31. #include "bit.h"
  32. #include "extern.h"
  33. #include "dmalloc.h"
  34.  
  35. /********************* Limits and defines ********************/
  36. #define MAXPATL  40        /* max pattern length       */
  37. #define MAXCFL  (MAXDLEN + MAXFLEN)    /* dir + fname length   */
  38.  
  39.  
  40. /***************** Local variables **************************/
  41.  
  42. static char fname[MAXFLEN + 3];    /* current selected finename  */
  43. static int rescan;        /* if update dir cache        */
  44. static char cmfn[MAXCFL + 2];    /* complet filename           */
  45. static char *dirname, *pattern;    /* points to different area   */
  46. static FL_OBJECT *browser;    /* alias to the acutal browser */
  47.  
  48. /*************** Local functions ***************************/
  49. static void create_the_forms(void);
  50.  
  51. /************* some utility functions ************/
  52.  
  53. /*****************************************************************
  54.  * Expand directory name and terminate it properly, i.e, ends in /
  55.  *****************************************************************/
  56. static char *
  57. fix_dir(char dir[])
  58. {
  59.     int k;
  60.  
  61.     if (fix_dirname(dir) != dir)
  62.       {
  63.       Bark("FioFixDir", "Something is wrong");
  64.       }
  65.  
  66.     k = strlen(dir);
  67.     return (dir[k - 1] != '/') ? strcat(dir, "/") : dir;
  68. }
  69.  
  70. /**************************************************************
  71.  * change/append an appropriate extension to the image filename
  72.  ***************************************************************/
  73. static void
  74. change_extension(char name[], const char *new)
  75. {
  76.     register char *p;
  77.  
  78.     if (auto_ext)        /* do extension only if requested */
  79.       {
  80.  
  81.       p = name + strlen(name) - 1;
  82.  
  83.       /* remove the extension */
  84.       while (p > name && *p != '.')
  85.           p--;
  86.       if (p <= name)
  87.           strcat(name, ".");
  88.       else
  89.           *++p = '\0';
  90.  
  91.       /* add the extension */
  92.       strcat(name, new);
  93.       }
  94. }
  95.  
  96.  
  97. /**************************************************************
  98.  * select files according to selection pattern
  99.  *************************************************************/
  100.  
  101. #include <sys/stat.h>
  102. static struct stat ffstat;
  103.  
  104. #if 0
  105. static int precheck = 1;    /* controls load_file routine */
  106. #endif
  107.  
  108. static int mload;        /* indicate if load_file      */
  109.  
  110. /***************************************************************
  111.  * show selected file names in the browser. Routine itself
  112.  * is blind in the sense that it doesn't care where is called
  113.  * and for what. It only manipulates object BR
  114.  ***************************************************************/
  115. static int
  116. load_browser(FL_OBJECT * br, const char *dir,
  117.          const char *pat, const char *fn)
  118. {
  119.     Dirlist *dirlist;
  120.     int i, fnumb;
  121.  
  122.     show_busy("ReadingDir ...");
  123.  
  124. #ifdef MDEBUG
  125.     M_debug("LoadBrowser", "dir=%s pat=%s file=%s", dir, pat, fn);
  126. #endif
  127.  
  128.     if (!(dirlist = get_dir_list(dir, pat, &fnumb, rescan)))
  129.       {
  130.       Bark("LoadDir", dir);
  131.       end_busy();
  132.       return -1;
  133.       }
  134.  
  135.     fl_freeze_form(br->form);
  136.     fl_clear_browser(br);
  137.  
  138.     for (i = 0; dirlist[i].name; i++)
  139.       {
  140.       if (dirlist[i].type == FT_DIR)
  141.         {
  142.         sprintf(cmfn, "D %s", dirlist[i].name);
  143.         fl_add_browser_line(br, cmfn);
  144.         }
  145.       else if (dirlist[i].type == FT_FILE)
  146.         {
  147.         fl_add_browser_line(br, dirlist[i].name);
  148.         if (fn && Streq(dirlist[i].name, fn))
  149.             fl_select_browser_line(br, i + 1);
  150.         }
  151.       }
  152.     fl_unfreeze_form(br->form);
  153.     end_busy();
  154.     return fnumb;
  155. }
  156.  
  157. /***************************************************************
  158.  *
  159.  *  A File Seclector.
  160.  *
  161.  **************************************************************/
  162.  
  163. #define FSELECT_CB 3
  164. static FL_FORM *load1;
  165. static FL_OBJECT *l1pat, *l1dir, *l1browser, *l1title;
  166. static FL_OBJECT *l1ok, *l1cancel;
  167.  
  168. static char l1dirname[MAXDLEN + 1];
  169. static char l1pattern[MAXPATL + 1];
  170. static char combined[MAXDLEN + MAXFLEN + 1];
  171.  
  172. /***********************************************************
  173.  * Global entry point to get a filename
  174.  ***********************************************************/
  175. const char *
  176. getfilename(const char *prom, const char *dir,
  177.         const char *pat, const char *fn, int block)
  178. {
  179.     int bd = 1;
  180.     FL_OBJECT *ret;
  181.     short val;
  182.     char *pf = 0;
  183.     const char *fnonly;
  184.  
  185.     create_the_forms();
  186.     strcpy(l1dirname, dir && *dir ? dir : ".");
  187.  
  188.     dirname = l1dirname;
  189.     Strncpy(l1pattern, pat && *pat ? pat : "*", MAXPATL);
  190.     pattern = l1pattern;
  191.     browser = l1browser;
  192.     strcpy(fname, fn);
  193.  
  194.     /* save current direcory info */
  195.     push_dir();
  196.  
  197.     fl_set_object_label(l1title, prom);
  198.     fix_dir(dirname);
  199.  
  200.     fl_deactivate_all_forms();
  201.     /* show default */
  202.     fl_set_input(l1dir, dirname);
  203.     fl_set_input(l1pat, pattern);
  204.     fl_set_input(l1title, fname);
  205.     load_browser(l1browser, dirname, pattern, fname);
  206.  
  207.     bit_show_form(load1, FL_PLACE_HOTSPOT, bd, "FileSelector");
  208.  
  209.     while ((ret = fl_do_forms()) != l1ok && ret != l1cancel)
  210.     if (ret == FL_EVENT)
  211.         (void) bit_qread(&val);
  212.  
  213.     bit_hide_form(load1);
  214.     fl_activate_all_forms();
  215.  
  216.     fnonly = fl_get_input(l1title);
  217.  
  218.     if (ret != l1cancel && fnonly && *fnonly)
  219.       {
  220.       Strncpy(fname, fnonly, MAXFLEN);
  221.       Strncpy(combined, fl_get_input(l1dir), MAXDLEN);
  222.       pf = strncat(fix_dir(combined), fname, MAXCFL);
  223.       }
  224.     pop_dir();
  225.     return pf;
  226. }
  227.  
  228. /******************************************************************
  229.  *
  230.  * Custom Form for write image to disk
  231.  *
  232.  ****************************************************************{*/
  233.  
  234. #define DUMP_CB 2
  235.  
  236. #define MAXSHOWN  14        /* max formats per screen          */
  237.  
  238.  
  239. static IMG_IO *wio[30];        /* all formats capabale of writing */
  240. static int totalwrite;        /* total number of formats that write */
  241. static int maxshown = MAXSHOWN;    /* acutal shown                    */
  242.  
  243. static FL_FORM *dump;
  244. static FL_OBJECT *dbrowser, *dok, *dcancel, *more, *ddir;
  245. static FL_OBJECT *dpat, *dfname, *dopt, *d_f[MAXSHOWN];
  246.  
  247. static char d_pattern[MAXPATL + 1];    /* selection pattern  */
  248. static char d_dirname[MAXDLEN + 1];    /* current directory  */
  249.  
  250. static void set_browser(FL_OBJECT *, const char *);
  251.  
  252. /*****************************************************************
  253.  * Gather all formats that can write and show them. we only need to
  254.  * do this once, because the no. of formats is a constant
  255.  ****************************************************************/
  256. static void
  257. init_formats(void)
  258. {
  259.     static int d_init;
  260.     int i;
  261.     register IMG_IO *ios = img_io + totalfmt, *io = img_io;
  262.  
  263.  
  264.     if (d_init)
  265.     return;
  266.  
  267.     /* get all formats that is writable */
  268.     while (io < ios)
  269.       {
  270.       if (io->dump)
  271.           wio[totalwrite++] = io;
  272.       io++;
  273.       }
  274.  
  275.     /* check if we have enuf button to show all formats */
  276.     if (maxshown >= totalwrite)
  277.       {                /* enuf button to show all formats */
  278.       fl_set_object_label(more, "All Formats");
  279.  
  280.       more->active = 0;    /* disable paging */
  281.  
  282.       /* also hide un-used buttons */
  283.       for (i = totalwrite; i < maxshown; i++)
  284.           fl_hide_object(d_f[i]);
  285.       }
  286.     else
  287.     /* not enuf buttons */
  288.       {
  289.       fl_set_object_label(more, "More Formats");
  290.       more->active = 1;    /* default. set it anyway */
  291.       }
  292.     d_init = 1;
  293. }
  294.  
  295. /***********************************************************************
  296.  * Take care of the case where more image formats than that can be shown
  297.  * per screen.
  298.  *
  299.  **********************************************************************/
  300. static int offset;        /* offset into the wio structure   */
  301. static int wcurrent;        /* selected format wio[current]    */
  302. static I_IO dumpinit;        /* get writing options             */
  303. static I_wdef dumpdef;        /* get options in string form      */
  304.  
  305. static void
  306. update_formats(void)
  307. {
  308.     int i;
  309.  
  310.     fl_freeze_form(dump);
  311.  
  312.     for (i = 0; i < maxshown && i + offset < totalwrite; i++)
  313.       {
  314.       fl_show_object(d_f[i]);
  315.       fl_set_object_label(d_f[i], wio[i + offset]->key);
  316.       fl_set_button(d_f[i], (wcurrent == i + offset));
  317.       }
  318.  
  319.     for (; i < maxshown; i++)
  320.     fl_hide_object_only(d_f[i]);
  321.  
  322.     fl_unfreeze_form(dump);
  323. }
  324.  
  325. /**********************************************************
  326.  * Paging
  327.  **********************************************************/
  328. /*ARGSUSED*/
  329. static void
  330. wformat_cb(FL_OBJECT * ob, long q)
  331. {
  332.     if (offset + maxshown <= totalwrite)
  333.     offset += maxshown;
  334.     else if (offset >= maxshown)
  335.     offset -= maxshown;
  336.     update_formats();
  337. }
  338.  
  339. /**********************************************************
  340.  * Requested another format to write
  341.  *********************************************************/
  342. /*ARGSUSED*/
  343. static void
  344. wformat_change(FL_OBJECT * ob, long q)
  345. {
  346.     int id;
  347.  
  348.     if (q + offset >= totalwrite)
  349.     return;
  350.  
  351.     wcurrent = id = q + offset;
  352.     dumpinit = wio[id]->dumpi;
  353.     dumpdef = wio[id]->wdef;
  354.     fl_set_object_label(dopt, dumpdef ? dumpdef(imgptr) : "None");
  355.     change_extension(fname, wio[id]->ext);
  356.     fl_set_input(dfname, fname);
  357.     set_browser(dbrowser, fname);
  358.     (!dumpinit ? fl_deactivate_object : fl_activate_object) (dopt);
  359. }
  360.  
  361.  
  362. /******* utility routine for external use *******/
  363. void
  364. update_dumpinfo(const char *s)
  365. {
  366.     fl_set_object_label(dopt, s);
  367. }
  368.  
  369. /***************************************************************
  370.  * Search a browser for name and show it in the browser. If outside
  371.  * viewing area, shift it to view
  372.  ****************************************************************/
  373. static void
  374. set_browser(FL_OBJECT * br, const char *name)
  375. {
  376.     register int i, maxline, match = 0;
  377.     int topline;
  378.  
  379.     maxline = fl_get_browser_maxline(br);
  380.     topline = fl_get_browser_topline(br);
  381.     fl_deselect_browser(br);
  382.  
  383.     for (i = 1; !match && i <= maxline; i++)
  384.     match = Streq(fl_get_browser_line(br, i), name);
  385.  
  386.     if (match)
  387.       {
  388.       fl_select_browser_line(br, --i);
  389.  
  390.       /* if the current is off viewing area, move it */
  391.       if (i < topline)
  392.           i--;
  393.       else if (i > topline + 11)
  394.           i -= 8;
  395.       else
  396.           i = -1;
  397.       if (i > 0)
  398.           fl_set_browser_topline(br, i);
  399.       }
  400. }
  401.  
  402.  
  403. static void fn_cb(FL_OBJECT *, long);
  404. static void dir_cb(FL_OBJECT *, long);
  405.  
  406. /*************************************************************
  407.  *  Global entry point for writing images to disk
  408.  ************************************************************/
  409. int
  410. do_dump(IPTR im)
  411. {
  412.     int bd = 1, id, err, follow_load_dir = 1;
  413.     short val;
  414.     FL_OBJECT *ret;
  415.  
  416.     create_the_forms();
  417.  
  418.     if (!image_ready(im, "Write"))
  419.     return -1;
  420.  
  421.     /* gather all formats capable of writing */
  422.     init_formats();
  423.  
  424.  
  425.     /* search currently requested format among the write-able formats */
  426.  
  427.     for (id = 0; id < totalwrite && im->io->key != wio[id]->key; id++)
  428.     ;
  429.  
  430.     if (id == totalwrite)
  431.       {
  432.       /*
  433.        * the current loaded image format is not capable of write, choose
  434.        * one that is. only reasonable that the chosen one has the same
  435.        * type
  436.        */
  437.  
  438.       if (IS_CI(im))
  439.         {
  440.         for (id = 0; id < totalwrite && wio[id]->type != T_CMAP; id++)
  441.             ;
  442.         }
  443.       else if (IS_CPACK(im))
  444.         {
  445.         for (id = 0; id < totalwrite && wio[id]->type != T_RGBA; id++)
  446.             ;
  447.         }
  448.  
  449.       /* if can't find match, get the first one */
  450.       im->io = wio[id %= totalwrite];
  451.       }
  452.  
  453.     offset = (id / maxshown);
  454.     offset *= maxshown;
  455.  
  456.     /* update reporting info and also initialization routine */
  457.     wcurrent = id;
  458.     update_formats();
  459.  
  460.     /* see if there is writing options */
  461.     update_dumpinfo(im->io->wdef ? im->io->wdef(im) : "None");
  462.  
  463.     /* functions to get writing options */
  464.     dumpinit = im->io->dumpi;
  465.  
  466.     /* get default writing parameters in string representation */
  467.     dumpdef = im->io->wdef;
  468.  
  469.     (dumpinit ? fl_activate_object : fl_deactivate_object) (dopt);
  470.  
  471.     /* save current direcotry */
  472.     push_dir();
  473.  
  474.     pattern = d_pattern;
  475.     dirname = d_dirname;
  476.     browser = dbrowser;
  477.  
  478.     fl_set_input(dpat, pattern);
  479.  
  480.     /* make it configuable some day */
  481.     follow_load_dir = 1;
  482.  
  483.     if (follow_load_dir)
  484.       {
  485.       getcwd(dirname, sizeof(d_dirname) - 2);
  486.       }
  487.     else
  488.       {
  489.       chdir(dirname);
  490.       }
  491.  
  492.     fix_dir(dirname);
  493.     fl_set_input(ddir, dirname);
  494.  
  495.     strcpy(im->ofile, im->ifile);
  496.     strcpy(fname, im->ofile);
  497.     fl_set_input(dfname, fname);
  498.  
  499.     load_browser(browser, dirname, pattern, fname);
  500.     set_browser(browser, fname);
  501.  
  502.     deactivate_all_forms();
  503.  
  504.     bit_show_form(dump, FL_PLACE_HOTSPOT, bd, "Write");
  505.  
  506.     /*
  507.      * the following do while loop only terminates if cancel or succesful
  508.      * write. Bad write will not terminate the loop
  509.      */
  510.     do
  511.       {
  512.       while ((ret = fl_do_forms()) != dok && ret != dcancel)
  513.         {
  514.         if (ret == FL_EVENT)
  515.           {
  516.               (void) bit_qread(&val);
  517.           }
  518.         else if (ret == dopt && dumpinit)
  519.           {
  520.               dumpinit(im);
  521.               update_dumpinfo(dumpdef ? dumpdef(im) : "None");
  522.           }
  523.         }
  524.       /* end of while loop: either cancel or write */
  525.  
  526.       if (wcurrent < 0 || wcurrent >= totalwrite)
  527.         {
  528.         Bark("ImageWrite", "can't happen");
  529.         return -1;
  530.         }
  531.  
  532.       id = wcurrent;
  533.  
  534.       /*
  535.        * it is very important that there is no modification to the
  536.        * writing parameters after writing has started. Also any file IO,
  537.        * image loading activities must be suspended (re-entrant
  538.        * problems).
  539.        */
  540.  
  541.       err = 0;
  542.       if (ret == dok)
  543.         {
  544.         dir_cb(ddir, 0);
  545.         fn_cb(dfname, 0);    /* check filename last time */
  546.  
  547.         fl_deactivate_all_forms();
  548.  
  549.         strcpy(im->ofile, fname);
  550.         set_current_window(dump->window);
  551.         err = write_image(wio[id], im, fname) < 0;
  552.         fl_activate_all_forms();
  553.         }
  554.       }
  555.     while (ret != dcancel && err);
  556.  
  557.     fl_activate_all_forms();
  558.     pop_dir();
  559.     bit_hide_form(dump);
  560.     return 0;
  561. }
  562.  
  563. /******************************************************************
  564.  * END OF writing routines
  565.  *****************************************************************}*/
  566.  
  567. /************************************************************
  568.  * Custom form for file loader
  569.  *
  570.  ***********************************************************/
  571. #define LOAD_CB 1
  572.  
  573. static FL_FORM *load;
  574. static FL_OBJECT *lmbrowser;
  575. static FL_OBJECT *ldir, *lpat, *ltotal, *loaded;
  576.  
  577. static char l_pattern[MAXPATL + 1];
  578. static char l_dirname[MAXDLEN + 1];
  579. static int totalf, loadedf;
  580.  
  581. /**************************************************************
  582.  * report  current active file list length
  583.  ************************************************************/
  584. static void
  585. show_loaded(void)
  586. {
  587.     char p[20];
  588.  
  589.     sprintf(p, "%4d Loaded", loadedf);
  590.     fl_set_object_label(loaded, p);
  591. }
  592.  
  593. #if 0
  594. static void
  595. pre_check_cb(FL_OBJECT * ob, long q)
  596. {
  597.     precheck = fl_get_button(ob);
  598. }
  599. #endif
  600.  
  601. /************************************************************
  602.  * load a mutitple-select browser. ff unused
  603.  ***********************************************************/
  604. static void
  605. zap_all_events(void)
  606. {
  607.     long dev;
  608.     short val;
  609.  
  610.     while (fl_check_forms() || fl_qtest())
  611.       {
  612.       dev = fl_qread(&val);
  613.       bit_handle_event(dev, val);
  614.       }
  615. }
  616.  
  617. /* ARGSUSED*/
  618. static int
  619. load_mbrowser(FL_OBJECT * br, const char *dir, const char *pat,
  620.           const char *ff)
  621. {
  622.     int i, fnumb;
  623.     Dirlist *dirlist;
  624.     static int in_lm;
  625.  
  626.     if (in_lm)
  627.       {
  628.       zap_all_events();
  629.       return -1;
  630.       }
  631.  
  632.     in_lm = 1;
  633.     show_busy("ReadingDir ...");
  634.  
  635.     if (!(dirlist = get_dir_list(dir, pat, &fnumb, rescan)))
  636.       {
  637.       Bark("LoadDir", dir);
  638.       end_busy();
  639.       in_lm = 0;
  640.       return -1;
  641.       }
  642.  
  643.     sprintf(cmfn, "%4d total", totalf = fnumb);
  644.     fl_set_object_label(ltotal, cmfn);
  645.  
  646.     loadedf = 0;
  647.     fl_freeze_form(br->form);
  648.     fl_clear_browser(br);
  649.  
  650.     for (i = 0; dirlist[i].name; i++)
  651.       {
  652.       if (dirlist[i].type == FT_DIR)
  653.         {
  654.         sprintf(cmfn, "D %s", dirlist[i].name);
  655.         fl_add_browser_line(br, cmfn);
  656.         }
  657.       else if (dirlist[i].type == FT_FILE)
  658.         {
  659.         fl_add_browser_line(br, dirlist[i].name);
  660.         /* highlight if selected */
  661.         if (is_on_list(dir, dirlist[i].name))
  662.           {
  663.               loadedf++;
  664.               fl_select_browser_line(br, i + 1);
  665.           }
  666.         }
  667.       }
  668.  
  669.     show_loaded();
  670.     fl_unfreeze_form(br->form);
  671.     end_busy();
  672.     in_lm = 0;
  673.     return fnumb;
  674. }
  675.  
  676. /*******************************************************************
  677.  * Global entry to making file list
  678.  *****************************************************************/
  679. void
  680. load_files(void)
  681. {
  682.     int bd = 1;
  683.     short val;
  684.  
  685.     create_the_forms();
  686.     mload = 1;
  687.  
  688.     dirname = l_dirname;
  689.     pattern = l_pattern;
  690.     browser = lmbrowser;
  691.     fix_dir(dirname);
  692.  
  693.     fl_set_input(ldir, dirname);
  694.     fl_set_input(lpat, pattern);
  695.     load_mbrowser(browser, dirname, pattern, "");
  696.  
  697.     deactivate_all_forms();
  698.  
  699.     bit_show_form(load, FL_PLACE_HOTSPOT, bd, "Load");
  700.  
  701.     while (bit_qread(&val) != KEYBD || val != 27)
  702.     ;
  703.     fl_activate_all_forms();
  704.     bit_hide_form(load);
  705.     mload = 0;
  706.     return;
  707. }
  708.  
  709. /********************************************************************
  710.  * common call back routines
  711.  ****************************/
  712.  
  713. /********** filename call back ******************/
  714. /* ARGSUSED */
  715. static void
  716. fn_cb(FL_OBJECT * obj, long arg)
  717. {
  718.     const char *p;
  719.  
  720.     p = fl_get_input(obj);
  721.     if (!p || !*p)
  722.       {
  723.       fl_set_input(obj, fname);
  724.       return;
  725.       }
  726.     strcpy(fname, p);
  727.     set_browser(browser, fname);
  728. }
  729.  
  730. /************** directory name call back ****************/
  731. static void
  732. dir_cb(FL_OBJECT * obj, long arg)
  733. {
  734.     const char *p;
  735.     char tmpdir[MAXDLEN + 2];
  736.  
  737.     p = fl_get_input(obj);
  738.  
  739.     if (!p || !*p)
  740.       {
  741.       fl_set_input(obj, dirname);
  742.       return;
  743.       }
  744.  
  745.     if (Streq(p, dirname))
  746.     return;
  747.  
  748.     /*
  749.      * this is necessary since static area in get_input is of a limited
  750.      * lenthg, last dirlen
  751.      */
  752.  
  753.     fix_dir(strcpy(tmpdir, p));
  754.  
  755.     if (stat(tmpdir, &ffstat) || !(ffstat.st_mode & S_IFDIR))
  756.       {
  757.       Bark("LoadDir", tmpdir);
  758.       fl_set_input(obj, dirname);
  759.       return;
  760.       }
  761.  
  762.     /* now, everying is ok, re-fill the browser */
  763.  
  764.     strcpy(dirname, tmpdir);
  765.     chdir(dirname);
  766.  
  767.     fl_set_input(obj, dirname);
  768.  
  769.     /* load either multi-selection browser or single */
  770.     (arg == LOAD_CB ? load_mbrowser : load_browser)
  771.     (browser, dirname, pattern, fname);
  772. }
  773.  
  774. /* pattern call back */
  775. static void
  776. pat_cb(FL_OBJECT * obj, long arg)
  777. {
  778.     const char *p;
  779.  
  780.     p = fl_get_input(obj);
  781.     if (!p)
  782.       {
  783.       fl_set_input(obj, dirname);
  784.       return;
  785.       }
  786.     if (Streq(p, pattern))
  787.     return;
  788.  
  789.     Strncpy(pattern, p, MAXPATL);
  790.  
  791.     if (arg == LOAD_CB)
  792.       {
  793.       load_mbrowser(browser, dirname, pattern, "");
  794.       }
  795.     else
  796.       {
  797.       load_browser(browser, dirname, pattern, fname);
  798.       }
  799. }
  800.  
  801. /*************************************************************
  802.  * browser call back
  803.  ************************************************************/
  804.  
  805. /* directory is marked by "D ". */
  806. #define is_a_dir(t)    (t[0] == 'D' && t[1] == ' ')
  807.  
  808. static void
  809. browser_cb(FL_OBJECT * br, long arg)
  810. {
  811.     char seltext[256];
  812.     char tmpdir[PATH_MAX];
  813.  
  814.     strcpy(seltext, fl_get_browser_line(br, fl_get_browser(br)));
  815.  
  816.     if (is_a_dir(seltext))
  817.       {
  818.       strcpy(seltext, seltext + 2);
  819.       strcat(strcpy(tmpdir, dirname), seltext);
  820.       fix_dir(tmpdir);
  821.       if (load_browser(br, tmpdir, pattern, fname) > 0)
  822.         {
  823.         strcpy(dirname, tmpdir);
  824.         fl_set_input(arg == FSELECT_CB ? l1dir : ddir, dirname);
  825.         }
  826.       }
  827.     else
  828.       {
  829.       fl_set_input(arg == FSELECT_CB ? l1title : dfname, seltext);
  830.       strcpy(fname, seltext);
  831.       }
  832. }
  833.  
  834. /****************************************************************
  835.  * sometimes, the form does not work right in the multi-select
  836.  * mode. workaround: if reported clicks are very close, probably
  837.  * wrong
  838.  ***************************************************************/
  839. #include <sys/time.h>
  840. #define SEP  600        /* milli sec */
  841. static int
  842. too_close(FL_OBJECT * br)
  843. {
  844.     static int lastline;
  845.     int i, j;
  846.  
  847.     j = ((i = fl_get_browser(br)) < 0) ? -i : i;
  848.  
  849.     /* relevent only if selected same line */
  850.     if (j == lastline)
  851.       {
  852.       if (time_passed() < SEP)
  853.         {
  854.         if (i > 0)
  855.             fl_deselect_browser_line(br, i);
  856.         return 1;
  857.         }
  858.       }
  859.     reset_time();
  860.     lastline = j;
  861.     return 0;
  862. }
  863.  
  864. /*******************************************************************
  865.  * multi-selection browser call back
  866.  *
  867.  * Here we must not double entry else if we hit a bad directory,
  868.  * recursion would occur.
  869.  *******************************************************************/
  870.  
  871.  
  872.  
  873. /* ARGSUSED */
  874. static void
  875. lbrowser_cb(FL_OBJECT * br, long NotUsed)
  876. {
  877.     char seltext[256];
  878.     char tmpdir[PATH_MAX];
  879.     static int in_lbcb;
  880.     int which = fl_get_browser(br);
  881.     int i = (which > 0) ? which : -which;
  882.  
  883.     if (too_close(br))
  884.     return;
  885.  
  886.     if (in_lbcb)
  887.       {
  888.       zap_all_events();
  889.       return;
  890.       }
  891.  
  892.  
  893.     in_lbcb = 1;
  894.  
  895.     strcpy(seltext, fl_get_browser_line(br, i));
  896.     if (is_a_dir(seltext))
  897.       {
  898.       strcpy(seltext, seltext + 2);
  899.  
  900.       /* check before proceed as not to overwrite current dir if error */
  901.       strcat(strcpy(tmpdir, dirname), seltext);
  902.       fix_dir(tmpdir);
  903.  
  904.       if (load_mbrowser(br, tmpdir, pattern, "") > 0)
  905.         {
  906.         strcpy(dirname, tmpdir);
  907.         fl_set_input(ldir, dirname);
  908.         }
  909.       }
  910.     else
  911.       {
  912.       if (which > 0)
  913.         {
  914.         if (!is_on_list(dirname, seltext))
  915.           {
  916.               add_to_list(dirname, seltext);
  917.               loadedf++;
  918.           }
  919.         }
  920.       else
  921.         {
  922.         if (is_on_list(dirname, seltext))
  923.           {
  924.               delete_from_list(dirname, seltext);
  925.               loadedf--;
  926.           }
  927.         }
  928.       }
  929.     show_loaded();
  930.     in_lbcb = 0;
  931. }
  932.  
  933. /* ARGSUSED */
  934. static void
  935. re_scan_cb(FL_OBJECT * p, long q)
  936. {
  937.     rescan = 1;
  938.     if (q == LOAD_CB)
  939.       {
  940.       load_mbrowser(browser, dirname, pattern, "");
  941.       }
  942.     else
  943.       {
  944.       load_browser(browser, dirname, pattern, fname);
  945.       }
  946.     rescan = 0;
  947. }
  948.  
  949. /* ARGSUSED */
  950. static void
  951. load_all_cb(FL_OBJECT * p, long q)
  952. {
  953.     int maxline = fl_get_browser_maxline(browser), i;
  954.     const char *sel;
  955.  
  956.     loadedf = 0;
  957.     show_busy("");
  958.     fl_freeze_form(browser->form);
  959.     for (i = maxline; i >= 1; i--)
  960.       {
  961.       sel = fl_get_browser_line(browser, i);
  962.       if (!is_a_dir(sel))
  963.         {
  964.         if (!is_on_list(dirname, sel))
  965.           {
  966.               add_to_list(dirname, sel);
  967.               fl_select_browser_line(browser, i);
  968.           }
  969.         loadedf++;
  970.         }
  971.       }
  972.     show_loaded();
  973.     fl_unfreeze_form(browser->form);
  974.     end_busy();
  975. }
  976.  
  977. /* ARGSUSED */
  978. static void
  979. unload_all_cb(FL_OBJECT * p, long q)
  980. {
  981.     int maxline = fl_get_browser_maxline(browser), i;
  982.     const char *sel;
  983.  
  984.     show_busy("");
  985.     fl_freeze_form(browser->form);
  986.     for (i = 1; i <= maxline; i++)
  987.       {
  988.       sel = fl_get_browser_line(browser, i);
  989.       if (!is_a_dir(sel) && is_on_list(dirname, sel))
  990.         {
  991.         delete_from_list(dirname, sel);
  992.         fl_deselect_browser_line(browser, i);
  993.         }
  994.       }
  995.     loadedf = 0;
  996.     show_loaded();
  997.     fl_unfreeze_form(browser->form);
  998.     end_busy();
  999. }
  1000.  
  1001.  
  1002. static void
  1003. create_form_dump(void)
  1004. {
  1005.     FL_OBJECT *obj;
  1006.     int i;
  1007.     float x, y, dx, dy;
  1008.  
  1009.     dump = fl_bgn_form(FL_NO_BOX, 325.0, 365.0);
  1010.     obj = fl_add_box(FL_UP_BOX, 0.0, 0.0, 325.0, 365.0, "");
  1011.     fl_set_object_color(obj, 12, 47);
  1012.     obj = fl_add_button(FL_HIDDEN_BUTTON, 0, 0, 325, 365, "");
  1013.     fl_set_call_back(obj, help_cb, HELP_WRITE);
  1014.  
  1015.     /* browser */
  1016.     dbrowser = fl_add_browser(FL_HOLD_BROWSER, 10.0, 70.0, 160.0, 220.0, "");
  1017.     fl_set_object_boxtype(dbrowser, FL_FRAME_BOX);
  1018.     fl_set_object_color(dbrowser, 8, 50);
  1019.     fl_set_call_back(dbrowser, browser_cb, DUMP_CB);
  1020.  
  1021.     /* Finemame */
  1022.     dfname = fl_add_input(FL_NI, 80.0, 40.0, 225.0, 20.0, "Filename:");
  1023.     fl_set_object_boxtype(dfname, FL_SHADOW_BOX);
  1024.     fl_set_object_color(dfname, 47, 51);
  1025.     fl_set_call_back(dfname, fn_cb, DUMP_CB);
  1026.  
  1027.  
  1028.     /* directory input */
  1029.     ddir = fl_add_input(FL_NI, 75.0, 325.0, 235.0, 20.0, "Directory:");
  1030.     fl_set_object_boxtype(ddir, FL_BORDER_BOX);
  1031.     fl_set_object_color(ddir, 12, 51);
  1032.     fl_set_object_lsize(ddir, 10.00);
  1033.     fl_set_call_back(ddir, dir_cb, DUMP_CB);
  1034.  
  1035.     /* pattern input */
  1036.     dpat = fl_add_input(FL_NI, 75.0, 305.0, 235.0, 20.0, "Pattern:");
  1037.     fl_set_object_boxtype(dpat, FL_BORDER_BOX);
  1038.     fl_set_object_color(dpat, 12, 51);
  1039.     fl_set_object_lsize(dpat, 10.0);
  1040.     fl_set_call_back(dpat, pat_cb, DUMP_CB);
  1041.  
  1042.     /* Options */
  1043.     obj = fl_add_text(FL_NT, 10.0, 15.0, 70.0, 20.0, "Options:");
  1044.     dopt = fl_add_button(FL_NORMAL_BUTTON, 80.0, 15.0, 225.0, 20.0, "");
  1045.     fl_set_object_boxtype(dopt, FL_BORDER_BOX);
  1046.     fl_set_object_lsize(dopt, 10.00);
  1047.  
  1048.     /* format group */
  1049.     fl_bgn_group();
  1050.     dx = 70;
  1051.     dy = 27;
  1052.     for (i = 0, x = 175, y = 235; i < maxshown - 1 && y > 90; i += 2, y -= dy)
  1053.       {
  1054.       d_f[i] = obj = fl_add_roundbutton(FL_RB, x, y, 30, 30, "");
  1055.       fl_set_object_lsize(obj, 10.00);
  1056.       fl_set_object_lstyle(obj, FL_BOLD_STYLE);
  1057.       fl_set_call_back(obj, wformat_change, i);
  1058.       d_f[i + 1] = obj = fl_add_roundbutton(FL_RB, x + dx, y, 30, 30, "");
  1059.       fl_set_object_lsize(obj, 10.0);
  1060.       fl_set_object_lstyle(obj, FL_BOLD_STYLE);
  1061.       fl_set_call_back(obj, wformat_change, i + 1);
  1062.       }
  1063.  
  1064.     maxshown = i;
  1065.     more = fl_add_button(FL_NB, 185.0, 270.0, 115.0, 20.0, "");
  1066.     fl_set_object_boxtype(more, FL_SHADOW_BOX);
  1067.     fl_set_object_lcol(more, 4);
  1068.     fl_set_object_lstyle(more, FL_ITALIC_STYLE);
  1069.     fl_set_call_back(more, wformat_cb, 0);
  1070.     fl_end_group();
  1071.  
  1072.     /* Ok  button */
  1073.     dok = fl_add_button(FL_NORMAL_BUTTON, 245.0, 70.0, 65.0, 25.0, "OK");
  1074.     fl_set_object_color(dok, 47, 2);
  1075.     fl_set_object_lsize(dok, 10.0);
  1076.  
  1077.     /* Cancel button */
  1078.     dcancel = fl_add_button(FL_NB, 175.0, 70.0, 65.0, 25.0, "Cancel");
  1079.     fl_set_object_color(dcancel, 47, 3);
  1080.     fl_set_object_lsize(dcancel, 10.0);
  1081.     fl_end_form();
  1082.     fl_set_form_hotspot(dump, (245 + 32), (70 + 13));
  1083. }
  1084.  
  1085.  
  1086. static void
  1087. mload_done(FL_OBJECT * ob, long q)
  1088. {
  1089.     fl_qenter(KEYBD, 27);
  1090. }
  1091.  
  1092.  
  1093. static void
  1094. create_form_load(void)
  1095. {
  1096.     FL_OBJECT *obj;
  1097.  
  1098.     load = fl_bgn_form(FL_NO_BOX, 285.0, 335.0);
  1099.     obj = fl_add_box(FL_UP_BOX, 0.0, 0.0, 285.0, 335.0, "");
  1100.     fl_set_object_color(obj, 9, 47);
  1101.     fl_set_object_align(obj, FL_ALIGN_RIGHT);
  1102.     obj = fl_add_button(FL_HIDDEN_BUTTON, 0, 0, 285, 335, "");
  1103.     fl_set_call_back(obj, help_cb, HELP_LOAD);
  1104.  
  1105.     /* directory input */
  1106.     ldir = fl_add_input(FL_NI, 50.0, 285.0, 225.0, 20.0, "Dir:");
  1107.     fl_set_object_boxtype(ldir, FL_BORDER_BOX);
  1108.     fl_set_object_color(ldir, 47, 50);
  1109.     fl_set_object_lsize(ldir, 10.00);
  1110.     fl_set_call_back(ldir, dir_cb, LOAD_CB);
  1111.  
  1112.     /* pattern input */
  1113.     lpat = fl_add_input(FL_NI, 50.0, 265.0, 225.0, 20.0, "Pat:");
  1114.     fl_set_object_boxtype(lpat, FL_BORDER_BOX);
  1115.     fl_set_object_color(lpat, 47, 50);
  1116.     fl_set_object_lsize(lpat, 10.00);
  1117.     fl_set_call_back(lpat, pat_cb, LOAD_CB);
  1118.  
  1119.     /* the brower */
  1120.     lmbrowser = obj = fl_add_browser(FL_MBR, 10.0, 10.0, 145.0, 230.0, "");
  1121.     fl_set_object_boxtype(obj, FL_SHADOW_BOX);
  1122.     fl_set_object_color(obj, 50, 12);
  1123.     fl_set_call_back(obj, lbrowser_cb, 0);
  1124.  
  1125.     /* reporting */
  1126.     ltotal = fl_add_text(FL_NORMAL_TEXT, 175.0, 210.0, 90.0, 20.0, "");
  1127.     fl_set_object_boxtype(ltotal, FL_BORDER_BOX);
  1128.     fl_set_object_lsize(ltotal, FL_SMALL_FONT);
  1129.     fl_set_object_align(ltotal, FL_ALIGN_CENTER);
  1130.     fl_set_object_lstyle(ltotal, FL_BOLD_STYLE);
  1131.     loaded = fl_add_text(FL_NORMAL_TEXT, 175.0, 190.0, 90.0, 20.0, "");
  1132.     fl_set_object_boxtype(loaded, FL_BORDER_BOX);
  1133.     fl_set_object_lsize(loaded, FL_SMALL_FONT);
  1134.     fl_set_object_align(loaded, FL_ALIGN_CENTER);
  1135.     fl_set_object_lstyle(loaded, FL_BOLD_STYLE);
  1136.  
  1137.     /* Control buttons */
  1138.     obj = fl_add_button(FL_NB, 175.0, 10.0, 90.0, 25.0, "Ready");
  1139.     fl_set_object_color(obj, FL_MAGIC1, FL_GREEN);
  1140.     fl_set_object_lsize(obj, 10.0);
  1141.     fl_set_call_back(obj, mload_done, 0);
  1142.     fl_set_form_hotspot(load, 175.0 + 45.0, 23.0);
  1143. #if 0
  1144.     obj = fl_add_button(FL_PB, 175.0, 150.0, 90.0, 25.0, "PreCheck");
  1145.     fl_set_object_lsize(obj, 10.0);
  1146.     fl_set_object_color(obj, FL_MAGIC1, FL_YELLOW);
  1147.     fl_set_button(obj, precheck);
  1148.     fl_set_call_back(obj, pre_check_cb, 0);
  1149. #endif
  1150.     obj = fl_add_button(FL_NB, 175.0, 125.0, 90.0, 25.0, "Load All");
  1151.     fl_set_object_color(obj, FL_MAGIC1, FL_YELLOW);
  1152.     fl_set_call_back(obj, load_all_cb, 0);
  1153.     fl_set_object_lsize(obj, 10.0);
  1154.     obj = fl_add_button(FL_NB, 175.0, 100.0, 90.0, 25.0, "Unload all");
  1155.     fl_set_object_color(obj, FL_MAGIC1, FL_YELLOW);
  1156.     fl_set_call_back(obj, unload_all_cb, 0);
  1157.     fl_set_object_lsize(obj, 10.0);
  1158.     obj = fl_add_button(FL_NB, 175.0, 75.0, 90.0, 25.0, "Re-scan");
  1159.     fl_set_object_color(obj, FL_MAGIC1, FL_BLUE);
  1160.     fl_set_call_back(obj, re_scan_cb, LOAD_CB);
  1161.     fl_set_object_lsize(obj, 10.0);
  1162.     fl_end_form();
  1163. }
  1164.  
  1165. static void
  1166. create_form_load1(void)
  1167. {
  1168.     FL_OBJECT *obj;
  1169.  
  1170.     load1 = fl_bgn_form(FL_NO_BOX, 290.0, 330.0);
  1171.     obj = fl_add_box(FL_UP_BOX, 0.0, 0.0, 290.0, 330.0, "");
  1172.  
  1173.     /* directory */
  1174.     l1dir = fl_add_input(FL_NORMAL_INPUT, 50.0, 295.0, 225.0, 20.0, "Dir:");
  1175.     fl_set_object_boxtype(l1dir, FL_BORDER_BOX);
  1176.     fl_set_object_color(l1dir, 47, 50);
  1177.     fl_set_object_lsize(l1dir, 10.000000);
  1178.     fl_set_call_back(l1dir, dir_cb, FSELECT_CB);
  1179.  
  1180.     /* the browser */
  1181.     l1browser = fl_add_browser(FL_HOLD_BROWSER, 10.0, 70.0, 140.0, 190.0, "");
  1182.     fl_set_object_boxtype(l1browser, FL_SHADOW_BOX);
  1183.     fl_set_object_color(l1browser, 50, 12);
  1184.     fl_set_call_back(l1browser, browser_cb, FSELECT_CB);
  1185.  
  1186.     /* pattern */
  1187.     l1pat = fl_add_input(FL_NORMAL_INPUT, 50.0, 275.0, 225.0, 20.0, "Pat:");
  1188.     fl_set_object_boxtype(l1pat, FL_BORDER_BOX);
  1189.     fl_set_object_color(l1pat, 47, 50);
  1190.     fl_set_object_lsize(l1pat, 10.00);
  1191.     fl_set_call_back(l1pat, pat_cb, FSELECT_CB);
  1192.  
  1193.     /* file input */
  1194.     l1title = fl_add_input(FL_NORMAL_INPUT, 30.0, 15.0, 225.0, 25.0, "");
  1195.     fl_set_object_boxtype(l1title, FL_SHADOW_BOX);
  1196.     fl_set_object_color(l1title, 47, 51);
  1197.     fl_set_object_lcol(l1title, FL_BLUE);
  1198.     fl_set_object_lsize(l1title, 10.000000);
  1199.     fl_set_object_align(l1title, FL_ALIGN_TOP);
  1200.  
  1201.     /* controls */
  1202.     l1ok = fl_add_button(FL_NB, 175.0, 75.0, 90.0, 25.0, "Ready");
  1203.     fl_set_object_color(l1ok, 47, 2);
  1204.     fl_set_object_lsize(l1ok, 10.000000);
  1205.     l1cancel = fl_add_button(FL_NB, 175.0, 110.0, 90.0, 25.0, "Cancel");
  1206.     fl_set_object_color(l1cancel, 47, 3);
  1207.     fl_set_object_lsize(l1cancel, 10.000000);
  1208.     obj = fl_add_button(FL_NB, 175.0, 230.0, 90.0, 25.0, "Re-scan");
  1209.     fl_set_object_lsize(obj, 10.000000);
  1210.     fl_set_call_back(obj, re_scan_cb, FSELECT_CB);
  1211.     fl_end_form();
  1212.     fl_set_form_hotspot(load1, (175 + 45), (75 + 12));
  1213. }
  1214.  
  1215. static void
  1216. create_the_forms(void)
  1217. {
  1218.     static int form_ok;
  1219.  
  1220.     if (form_ok)
  1221.     return;
  1222.     create_form_dump();
  1223.     create_form_load();
  1224.     create_form_load1();
  1225.     strcpy(d_dirname, startdir);
  1226.     strcpy(l_dirname, ".");
  1227.     strcpy(d_pattern, "*");
  1228.     strcpy(l_pattern, "*");
  1229.     form_ok = 1;
  1230. }
  1231.